#!/usr/bin/perl

################################################################
## This file is to parse the vector file to Piecewise Linear(PWL)
##   format for spectre stimuli.
##
## The vector file must meet the required format. Please refer to
##   to the example vector file 'stimuli.vec'.
##
## Written for ECE432/ECE632 class, Nov. 27, 2007
################################################################

$infile = $ARGV[0];
$outfile = $ARGV[1];

# Open files
open(IN, "$infile") || die("Could not open file!");
open(OUT, ">$outfile") || die("Could not open file!");


my %HoH = ();

# Parse the vector header
while ($line = <IN>) {
    chomp($line);
    @cols = split(/\s+/, $line);
    if ($line =~ /^radix/) {
	@bitNum = @cols; 
    }
    elsif ($line =~ /^vname/) {
	@vname = @cols;
	for ($i=1; $i<$#vname+1; $i++) {
	    $HoH->{$vname[$i]}->{'bits'} = $bitNum[$i];
	}
    }
    elsif ($line =~ /^tunit/) {
	if ($cols[1] eq 's') {
	    $tunit = "";
	} else {
	    $tunit = substr($cols[1], 0, 1);
	}
    }
    elsif ($line =~ /^trise/) {
	$trise = $cols[1];
    }
    elsif ($line =~ /^tfall/) {
	$tfall = $cols[1];
    }
    elsif ($line =~ /^vih/) {
	$vih = $cols[1];
    }
    elsif ($line =~ /^vil/) {
	$vil = $cols[1];
    }
    elsif ($line =~ /^\d/) {
	for ($i=1; $i<$#cols+1; $i++) {
	   $HoH->{$vname[$i]}->{$cols[0]} = $cols[$i];
	}
    }
    else {
    }
}

print OUT "simulator lang=spectre\n\n";

# Parse each bit to the Piecewise Linear (PWL) format
for my $wave (keys %$HoH) {
    $bits = $HoH->{$wave}->{'bits'};
    delete $HoH->{$wave}->{'bits'};
    if ($bits==1) {
	print OUT "V$wave ($wave 0) vsource type=pwl wave=\\[";
        for my $t (sort keys %{$HoH->{$wave}}) {
	    $v = $HoH->{$wave}->{$t};
	    # Parse to PWL format for spectre
	    if ($v==1) {
		$value=$vih;
	    } else {
		$value=$vil;
	    }  	  
	    if ($t==0) {
		print OUT "$t$tunit $value ";
	    } elsif ($value!=$prev) {
		if ($value==$vih) {
		   $t0=$t-$trise;
		} else {
		   $t0=$t-$tfall;
		} 
		print OUT "$t0$tunit $prev $t$tunit $value ";
	    }
	    $prev = $value;   
        }
        print OUT "]\n";
    }
    else {
 	# Parse each bit of the bus vector
        for ($i=0; $i<$bits; $i++) {
	    print OUT "V$wave\_$i ($wave\_$i 0) vsource type=pwl wave=\\[";
	    for my $t (sort keys %{$HoH->{$wave}}) {
	        $vs = $HoH->{$wave}->{$t};
		if ($bits!=length($vs)) {
		    print "ERROR: The size of the vector for $wave at time $t is not equal to its radix!\n";
		    return;
		}
		$v = substr($vs, $bits-1-$i, 1);
		# Parse to Piecewise Linear (PWL) Vector for spectre
		if ($v==1) {
		    $value=$vih;
		} else {
		    $value=$vil;
		}  	  
		if ($t==0) {
		    print OUT "$t$tunit $value ";
		} elsif ($value!=$prev) {
		    if ($value==$vih) {
		       $t0=$t-$trise;
		    } else {
		       $t0=$t-$tfall;
		    } 
		    print OUT "$t0$tunit $prev $t$tunit $value ";
		}
		$prev = $value;   
	    }
	    print OUT "]\n";
       }
    }
}

# Close files
close(infile);
close(outfile);





